import { expect, test, Response as PwResponse } from "@playwright/test";
import { validateMd5 } from "../../utils";

/*
 * `curl -s https://opennext.js.org/share.png | md5sum`
 * This is the MD5 hash of the image. It is used to validate the image content.
 */
const OPENNEXT_PNG_MD5 = "405f45cc3397b09717a13ebd6f1e027b";

test("Middleware Rewrite", async ({ page }) => {
	await page.goto("/");
	await page.getByRole("link", { name: "/Rewrite" }).click();

	await page.waitForURL("/rewrite");
	let el = page.getByText("Rewritten Destination", { exact: true });
	await expect(el).toBeVisible();

	// Loading page should also rewrite
	await page.goto("/rewrite");
	await page.waitForURL("/rewrite");
	el = page.getByText("Rewritten Destination", { exact: true });
	await expect(el).toBeVisible();
});

test("Middleware Rewrite External Image", async ({ page }) => {
	let responsePromise = new Promise<PwResponse>((resolve) => {
		page.on("response", async (resp) => {
			resolve(resp);
		});
	});

	await page.goto("/rewrite-external");

	const response = await responsePromise;

	expect(response.status()).toBe(200);
	expect(response.headers()["content-type"]).toBe("image/png");
	expect(response.headers()["cache-control"]).toBe("max-age=600");
	const bodyBuffer = await response.body();
	expect(validateMd5(bodyBuffer, OPENNEXT_PNG_MD5)).toBe(true);
});

test("Middleware Rewrite Status Code", async ({ page }) => {
	// Need to set up the event before navigating to the page to avoid missing it
	// We need to check the URL here also cause there will be multiple responses (i.e the fonts, css, js, etc)
	const statusPromise = new Promise<number>((resolve) => {
		page.on("response", async (response) => {
			// `response.url()` will be the full URL including the host, so we need to check the pathname
			if (new URL(response.url()).pathname === "/rewrite-status-code") {
				resolve(response.status());
			}
		});
	});

	await page.goto("/rewrite-status-code");
	const el = page.getByText("Rewritten Destination", { exact: true });
	await expect(el).toBeVisible();
	expect(statusPromise).resolves.toEqual(403);
});
